home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 January: Mac OS SDK / Dev.CD Jan 97 SDK2.toast / Development Kits (Disc 2) / OpenDoc / OpenDoc Development / Debugging Support / OpenDoc™ Source Code / Imaging / RealShapes / RgnShpe.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1996-08-28  |  6.3 KB  |  356 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        RgnShpe.h
  3.  
  4.     Contains:    RgnShape class, private to ODShape.
  5.  
  6.     Owned by:    Jens Alfke
  7.  
  8.     Copyright:    © 1993 - 1995 by Apple Computer, Inc., all rights reserved.
  9.  
  10.     Change History (most recent first):
  11.     
  12.         <10>     8/29/95    jpa        Throw kODErrInvalidPlatformShape if NULL
  13.                                     region passed in. [12788284]
  14.          <9>     8/16/95    NP        1274946: ErrorDef.idl problems. Add include
  15.                                     file.
  16.          <8>      8/8/95    jpa        Got rid of CATCH(): not native-exceptions
  17.                                     compatible. [1268187]
  18.          <7>     12/5/94    jpa        Implemented CopyGXShape. [1195654]
  19.          <6>    10/24/94    jpa        Use RealShape::NewGeometricShape to
  20.                                     promote. [1195070]
  21.          <5>     9/29/94    RA        1189812: Mods for 68K build.
  22.          <4>     9/14/94    jpa        Outset converts distance to short before
  23.                                     calling InsetRgn. [1183857]
  24.          <3>      8/8/94    jpa        Added Outset method [1178690]
  25.          <2>     6/18/94    MB        Update memory includes
  26.          <1>     6/15/94    jpa        first checked in
  27.  
  28.     In Progress:
  29.         
  30. */
  31.  
  32.  
  33. #ifndef _ALTPOINT_
  34. #include "AltPoint.h"            /* Use C++ savvy ODPoint and ODRect*/
  35. #endif
  36.  
  37. #ifndef _ALTPOLY_
  38. #include "AltPoly.h"
  39. #endif
  40.  
  41. #ifndef _RGNSHPE_
  42. #include "RgnShpe.h"
  43. #endif
  44.  
  45. #ifndef _POLYSHPE_
  46. #include "PolyShpe.h"
  47. #endif
  48.  
  49. #ifndef SOM_ODTransform_xh
  50. #include "Trnsform.xh"
  51. #endif
  52.  
  53. #ifndef _RGN2PLYM_
  54. #include "Rgn2PlyM.h"
  55. #endif
  56.  
  57. #ifndef _EXCEPT_
  58. #include "Except.h"
  59. #endif
  60.  
  61. #ifndef _ODMEMORY_
  62. #include "ODMemory.h"
  63. #endif
  64.  
  65. #ifndef _ODMATH_
  66. #include <ODMath.h>
  67. #endif
  68.  
  69. #ifndef _ODDEBUG_
  70. #include "ODDebug.h"
  71. #endif
  72.  
  73. #ifndef _UTILERRS_
  74. #include "UtilErrs.h"
  75. #endif
  76.  
  77.  
  78. RgnShape::RgnShape( ODGeometryMode mode )
  79.     :RealShape(mode),
  80.      fPolygon()
  81. {
  82. #if ODDebug
  83.     fType = 1;
  84. #endif
  85. }
  86.  
  87.  
  88. RgnShape::~RgnShape( )
  89. {
  90.     this->Purge(0);
  91.     RealShape::Purge(0);            // Dispose rgn too
  92. }
  93.  
  94.  
  95. ODSize
  96. RgnShape::Purge( ODSize )
  97. {
  98.     // Don't dispose the region like my parent class!
  99.     if( fPolygon.HasData() ) {
  100.         ODSize size = fPolygon.GetDataSize();
  101.         fPolygon.Clear();
  102.         return size;
  103.     } else
  104.         return 0;
  105. }
  106.  
  107.  
  108. void
  109. RgnShape::GetBoundingBox( ODRect *bounds )
  110. {
  111.     if( fQDRegion ) {
  112.         Rect bbox = (**fQDRegion).rgnBBox;
  113.         *bounds = bbox;
  114.     } else
  115.         bounds->Clear();
  116. }
  117.  
  118.  
  119. RealShape*
  120. RgnShape::SetRectangle( const ODRect *r )
  121. {
  122.     if( !fQDRegion ) {
  123.         fQDRegion = ODNewRgn();
  124.         THROW_IF_NULL(fQDRegion);
  125.     }
  126.     Rect qdr;
  127.     r->AsQDRect(qdr);
  128.     RectRgn(fQDRegion,&qdr);
  129.     this->Purge(0);
  130.     return this;
  131. }
  132.  
  133.  
  134. RealShape*
  135. RgnShape::Clear( )
  136. {
  137.     SetRectRgn(fQDRegion,0,0,0,0);
  138.     this->Purge(0);
  139.     return this;
  140. }
  141.  
  142.  
  143. void
  144. RgnShape::CopyPolygon( ODPolygon &poly )
  145. {
  146.     if( !fPolygon.HasData() )
  147.         Rgn2Poly(fQDRegion,fPolygon);
  148.     poly.CopyFrom(fPolygon);
  149. }
  150.  
  151.  
  152. RealShape*
  153. RgnShape::SetPolygon( const ODPolygon &poly )
  154. {
  155.     RgnHandle rgn = poly.AsQDRegion();
  156.     this->Purge(0);
  157.     fQDRegion = rgn;
  158.     
  159.     TRY{
  160.         fPolygon.CopyFrom(poly);
  161.     }CATCH_ALL{
  162.         if( ErrorCode() == kODErrOutOfMemory )
  163.             fPolygon.Clear();            // It's okay if poly couldn't be copied
  164.         else
  165.             RERAISE;
  166.     }ENDTRY
  167.     
  168.     return this;
  169. }
  170.  
  171.  
  172. void
  173. RgnShape::InitQDRegion( )
  174. {
  175. }
  176.  
  177.  
  178. gxShape
  179. RgnShape::CopyGXShape( )
  180. {
  181.     if( !fPolygon.HasData() )
  182.         Rgn2Poly(fQDRegion,fPolygon);
  183.     return fPolygon.AsGXShape();
  184. }
  185.  
  186.  
  187. void
  188. RgnShape::SetPlatformShape( ODGraphicsSystem system, ODPlatformShape shape )
  189. {
  190.     ASSERT(system==kODQuickDraw,kODErrAssertionFailed);
  191.     if( shape==kODNULL )
  192.         THROW(kODErrInvalidPlatformShape);
  193.     
  194.     RealShape::Purge(0);
  195.     fQDRegion = (RgnHandle)shape;
  196. }
  197.  
  198.  
  199. ODBoolean
  200. RgnShape::IsSameAs( RealShape *shape )
  201. {
  202.     ASSERT_NOT_NULL(fQDRegion);
  203.     if( shape==this )
  204.         return kODTrue;
  205.     Boolean empty = this->IsEmpty();
  206.     Boolean shapeEmpty = shape->IsEmpty();
  207.     if( empty || shapeEmpty )
  208.         return empty==shapeEmpty;
  209.         
  210.     return EqualRgn(fQDRegion, (RgnHandle)shape->GetPlatformShape(kODQuickDraw));
  211. }
  212.  
  213.  
  214. ODBoolean
  215. RgnShape::IsEmpty( )
  216. {
  217.     ASSERT_NOT_NULL(fQDRegion);
  218.     return EmptyRgn(fQDRegion);
  219. }
  220.  
  221.  
  222. ODBoolean
  223. RgnShape::ContainsPoint( ODPoint point )
  224. {
  225.     ASSERT_NOT_NULL(fQDRegion);
  226.     return PtInRgn(point.AsQDPoint(),fQDRegion);
  227. }
  228.  
  229.  
  230. ODBoolean
  231. RgnShape::IsRectangular( )
  232. {
  233.     ASSERT_NOT_NULL(fQDRegion);
  234.     return GetHandleSize((Handle)fQDRegion)==sizeof(Region);
  235.     // (Empty region has no extra data past the end of its struct.)
  236. }
  237.  
  238.  
  239. ODBoolean
  240. RgnShape::HasGeometry( )
  241. {
  242.     return kODTrue /*this->IsRectangular()*/;
  243. }
  244.  
  245.  
  246. RealShape*
  247. RgnShape::Copy( )
  248. {
  249.     ASSERT_NOT_NULL(fQDRegion);
  250.     RgnHandle r = (RgnHandle) ODCopyHandle((ODHandle)fQDRegion);
  251.     RgnShape* s;
  252.     TRY{
  253.         s = new RgnShape(fMode);
  254.     }CATCH_ALL{
  255.         DisposeRgn(r);
  256.         RERAISE;
  257.     }ENDTRY
  258.     s->SetPlatformShape(kODQuickDraw,r);
  259.     return s;
  260. }
  261.  
  262.  
  263. RealShape*
  264. RgnShape::Transform( Environment *ev, ODTransform *xform )
  265. {
  266.     ASSERT_NOT_NULL(fQDRegion);
  267.     if( !EmptyRgn(fQDRegion) )
  268.         if( xform->IsQDOffset(ev) ) {
  269.             Point offset = xform->GetQDOffset(ev);
  270.             OffsetRgn(fQDRegion,offset.h,offset.v);        // QD offset: just offset region
  271.             if( fPolygon.HasData() )
  272.                 fPolygon.Transform(ev,xform);            // ...and cached polygon (if any)
  273.             
  274.         } else {
  275.             // Must promote myself to a polygon and try again.
  276.             if( !fPolygon.HasData() )
  277.                 Rgn2Poly(fQDRegion,fPolygon);
  278.             RealShape *polyShape = RealShape::NewGeometricShape(fMode);
  279.             TRY{
  280.                 polyShape->SetPolygon(fPolygon);        // fPolygon is always simple
  281.                 polyShape->Transform(ev,xform);
  282.             }CATCH_ALL{
  283.                 delete polyShape;
  284.                 RERAISE;
  285.             }ENDTRY
  286.             delete this;
  287.             return polyShape;
  288.         }
  289.     
  290.     return this;
  291. }
  292.  
  293.  
  294. RealShape*
  295. RgnShape::Outset( ODCoordinate distance )
  296. {
  297.     ASSERT_NOT_NULL(fQDRegion);
  298.     if( !EmptyRgn(fQDRegion) ) {
  299.         short intDist = ODFixedRound(-distance);
  300.         InsetRgn(fQDRegion,intDist,intDist);
  301.         this->Purge(0);
  302.     }
  303.     return this;
  304. }
  305.  
  306.  
  307. RealShape*
  308. RgnShape::Subtract( RealShape *shape )
  309. {
  310.     ASSERT_NOT_NULL(fQDRegion);
  311.     if( shape==this )
  312.         return this->Clear();
  313.     else if( !this->IsEmpty() && !shape->IsEmpty() )    {
  314.         ODRect bounds;
  315.         Rect b, sect;
  316.         shape->GetBoundingBox(&bounds);
  317.         bounds.AsQDRect(b);
  318.         if( SectRect(&b,&(**fQDRegion).rgnBBox,§) ) {
  319.             DiffRgn(fQDRegion, shape->GetQDRegion(), fQDRegion);
  320.             this->Purge(0);
  321.         }
  322.     }
  323.     return this;
  324. }
  325.  
  326.  
  327. RealShape*
  328. RgnShape::Intersect( RealShape *shape )
  329. {
  330.     ASSERT_NOT_NULL(fQDRegion);
  331.     if( shape!=this && !this->IsEmpty() )    {
  332.         ODRect bounds;
  333.         Rect b, sect;
  334.         shape->GetBoundingBox(&bounds);
  335.         bounds.AsQDRect(b);
  336.         if( !bounds.IsEmpty() && SectRect(&b,&(**fQDRegion).rgnBBox,§) )
  337.             SectRgn(fQDRegion, shape->GetQDRegion(), fQDRegion);
  338.         else
  339.             SetRectRgn(fQDRegion, 0,0,0,0);
  340.         this->Purge(0);
  341.     }
  342.     return this;
  343. }
  344.  
  345.  
  346. RealShape*
  347. RgnShape::Union( RealShape *shape )
  348. {
  349.     ASSERT_NOT_NULL(fQDRegion);
  350.     if( shape!=this && !shape->IsEmpty() )    {
  351.         UnionRgn(fQDRegion, shape->GetQDRegion(), fQDRegion);
  352.         this->Purge(0);
  353.     }
  354.     return this;
  355. }
  356.